package manager;

import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import utils.DBConnector;
import utils.LockUtil;
import utils.OverlapingUtil;

/**
 * Servlet implementation class AddCourseUser
 */
public class AddCourseUser extends BaseCMServlet {
	private static final long serialVersionUID = 1L;
       
    
	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		if (request.getSession(false) == null || request.getSession(false).getAttribute("username") == null){
			response.sendError(HttpServletResponse.SC_FORBIDDEN, "Please login first");
			return;
		}
		
		
		String username = request.getSession(false).getAttribute("username").toString();
		
		DBConnector dbConn = null;
		try {		
			dbConn = new DBConnector();
			PreparedStatement capacCountStmnt = dbConn.getConnection().prepareStatement(
					"SELECT capacity, (SELECT COUNT(username) FROM user_courses WHERE course_name = ?) AS registered from courses " +
					"WHERE course_name = ? AND is_active = TRUE; ");		
			
	
			PreparedStatement insertStmnt = dbConn.getConnection().prepareStatement(
						"INSERT into user_courses " +
						" values (?, ?) ;");
			
			
			insertStmnt.setString(2, username);
			
			String[] courseNames = request.getParameterValues("check");
			if (courseNames == null){
				response.sendRedirect("user_manage_courses.jsp");
				return;
			}
			
			String erroMessage = new String("");
			
			synchronized(LockUtil.getUserCoursesLock()) {
				for (String courseName : courseNames){
					capacCountStmnt.setString(1, courseName);
					capacCountStmnt.setString(2, courseName);
					ResultSet capacityRS = capacCountStmnt.executeQuery();
					capacityRS.next();
					if (capacityRS.getInt(2) >= capacityRS.getInt(1)){
						response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "course is full");
						return;
					}
				
					// Check for overlapping
					PreparedStatement overlapStmnt = dbConn.getConnection().prepareStatement(
							"SELECT c.course_name, session_start_time, session_end_time, session_day \n" +
							"FROM courses c, course_sessions cs \n" + 
							"WHERE c.course_name = cs.course_name AND \n" +
							"( c.course_name in  (SELECT uc2.course_name FROM user_courses uc2 WHERE uc2.username = ?) \n" +
							" or c.course_name = ?) \n" +
							"ORDER BY session_day, c.course_name");
					
					overlapStmnt.setString(1, username);
					overlapStmnt.setString(2, courseName);
					
					ResultSet res = overlapStmnt.executeQuery();
					
					OverlapingUtil olu = new OverlapingUtil();
					
					int lastDay = 0;
					
					while(res.next()) {
						int start_time = res.getInt("session_start_time");
						int end_time = res.getInt("session_end_time");
						if (lastDay != res.getInt("session_day")){
							lastDay = res.getInt("session_day");
							olu = new OverlapingUtil();
						}
						olu.addSegment(start_time, end_time);
						if (olu.isOverlapping()) {
							break;
						}
					}
					
					if (olu.isOverlapping()) {
						erroMessage += courseName + ","; 
						continue;
					}
					insertStmnt.setString(1, courseName);
					insertStmnt.execute();
				}
			}

			if(!erroMessage.equals("")){
				response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, 
						"Sessions Overlap with courses: " + erroMessage.substring(0, erroMessage.length() - 1) );
				return;
			}
			response.sendRedirect("user_manage_courses.jsp");
						
						
		
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			// TODO gal, what is the error here ??
			response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Internal Error");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
		finally {
			try {
				dbConn.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

}
